home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagg_m.zip / GRAPHICS.SWG / 0132_X3dunit.pas < prev    next >
Pascal/Delphi Source File  |  1994-08-24  |  10KB  |  410 lines

  1. unit x3dunit2;
  2.  
  3. { mode-x 3D unit - xhlin-procedure by Sean Palmer }
  4. { Optimized by Luis Mezquita Raya                 }
  5.  
  6. {$g+}
  7.  
  8. interface
  9.  
  10. const vidseg:word=$a000;
  11.       divd:word=128;
  12.       dist:word=200;
  13.       minx:word=0;
  14.       maxx:word=319;
  15.       border:boolean=false;
  16.  
  17. var   ctab:array[byte] of integer;
  18.       stab:array[byte] of integer;
  19.       address:word;
  20.       triangles:boolean;
  21.  
  22. Procedure setborder(col:byte);
  23. Procedure setpal(c,r,g,b:byte);
  24. Procedure retrace;
  25. Procedure setmodex;
  26. Procedure setaddress(ad:word);
  27. Procedure cls;
  28. Procedure polygon(x1,y1,x2,y2,x3,y3,x4,y4:integer; c:byte);
  29. Function  cosinus(i:byte):integer;
  30. Function  sinus(i:byte):integer;
  31.  
  32. implementation
  33.  
  34. var   xpos:array[0..199,0..1] of integer;
  35.  
  36. Procedure setborder(col:byte); assembler;
  37. asm
  38.         xor ch,ch
  39.         mov cl,border
  40.         jcxz @out
  41.         mov dx,3dah
  42.         in al,dx
  43.         mov dx,3c0h
  44.         mov al,11h+32
  45.         out dx,al
  46.         mov al,col
  47.         out dx,al
  48. @out:
  49. end;
  50.  
  51. Procedure setpal(c,r,g,b:byte); assembler;
  52. asm
  53.         mov dx,3c8h
  54.         mov al,[c]
  55.         out dx,al
  56.         inc dx
  57.         mov al,[r]
  58.         out dx,al
  59.         mov al,[g]
  60.         out dx,al
  61.         mov al,[b]
  62.         out dx,al
  63. end;
  64.  
  65. Procedure retrace; assembler;
  66. asm
  67.         mov dx,3dah;
  68. @vert1: in al,dx
  69.         test al,8
  70.         jz @vert1
  71. @vert2: in al,dx
  72.         test al,8
  73.         jnz @vert2
  74. end;
  75.  
  76. Procedure setmodex; assembler;
  77. asm
  78.         mov ax,13h
  79.         int 10h
  80.         mov dx,3c4h
  81.         mov ax,0604h
  82.         out dx,ax
  83.         mov ax,0f02h
  84.         out dx,ax
  85.         mov cx,320*200
  86.         mov es,vidseg
  87.         xor ax,ax
  88.         mov di,ax
  89.         rep stosw
  90.         mov dx,3d4h
  91.         mov ax,0014h
  92.         out dx,ax
  93.         mov ax,0e317h
  94.         out dx,ax
  95. end;
  96.  
  97. Procedure setaddress(ad:word); assembler;
  98. asm
  99.         mov dx,3d4h
  100.         mov al,0ch
  101.         mov ah,[byte(ad)+1]
  102.         out dx,ax
  103.         mov al,0dh
  104.         mov ah,[byte(ad)]
  105.         out dx,ax
  106. end;
  107.  
  108. Procedure cls; assembler;
  109. asm
  110.         mov es,vidseg
  111.         mov di,address
  112.         mov cx,8000
  113.         mov dx,3c4h
  114.         mov ax,0f02h
  115.         out dx,ax
  116.         xor ax,ax
  117.         rep stosw
  118. end;
  119.  
  120. {$f-}
  121.  
  122. Procedure polygon(x1,y1,x2,y2,x3,y3,x4,y4:integer; c:byte); assembler;
  123. var mny,mxy,y,m,mult,divi,top,s,
  124.     stb,px1,py1,px2,py2:integer;
  125.     dir:byte;
  126. asm                                     { Procedure Polygon }
  127.         mov ax,y1                       { Determine lowest & highest points }
  128.         mov cx,ax
  129.         mov bx,y2
  130.  
  131.         cmp ax,bx                       { if mny>y2 ==> mny:=y2 }
  132.         jl @p2
  133.         mov ax,bx
  134.  
  135. @p2:    cmp cx,bx                       { if mxy<y2 ==> mxy:=y2 }
  136.         jg @p3
  137.         mov cx,bx
  138.  
  139. @p3:    mov bx,y3
  140.         cmp ax,bx                       { if mny>y3 ==> mny:=y3 }
  141.         jl @p3M
  142.         mov ax,bx
  143.  
  144. @p3M:   cmp cx,bx                       { if mxy<y3 ==> mxy:=y3 }
  145.         jg @p4
  146.         mov cx,bx
  147.  
  148. @p4:    mov bx,y4
  149.         cmp ax,bx                       { if mny>y4 ==> mny:=y4 }
  150.         jl @p4M
  151.         mov ax,bx
  152.  
  153. @p4M:   cmp cx,bx                       { if mxy<y4 ==> mxy:=y4 }
  154.         jg @vert
  155.         mov cx,bx
  156.  
  157. @vert:  cmp ax,0                        { Vertical range checking }
  158.         jge @minin                      { if mny<0 ==> mny:=0 }
  159.         xor ax,ax
  160. @minin: cmp cx,200                      { if mxy>199 ==> mxy:=199 }
  161.         jl @maxin
  162.         mov cx,199
  163. @maxin: cmp cx,0                        { if mxy<0 ==> Exit }
  164.         jl @pexit
  165.         cmp ax,199                      { if mny>199 ==> Exit }
  166.         jg @pexit
  167.  
  168.         mov mny,ax                      { ax=mny=lowest point }
  169.         mov mxy,cx                      { cx=mxy=highest point }
  170.  
  171.         push x1                         { RangeChk(x1,y1,x2,y2) }
  172.         push y1
  173.         push x2
  174.         push y2
  175.         call @Range
  176.  
  177.         push x2                         { RangeChk(x2,y2,x3,y3) }
  178.         push y2
  179.         push x3
  180.         push y3
  181.         call @Range
  182.  
  183.         push x3                         { RangeChk(x3,y3,x4,y4) }
  184.         push y3
  185.         cmp Triangles,0
  186.         jz @Poly4
  187.         push x1
  188.         push y1
  189.         jmp @Last
  190.  
  191. @Poly4: push x4
  192.         push y4
  193.         call @Range
  194.  
  195.         push x4                         { RangeChk(x4,y4,x1,y1) }
  196.         push y4
  197.         push x1
  198.         push y1
  199. @Last:  call @Range
  200.  
  201.         mov ax,mny                      { Show a poly }
  202.         mov di,ax                       { y:=mny }
  203.         shl di,2
  204.         lea bx,xpos
  205.         add di,bx                       { di points to xpos[y,0] }
  206. @Show:  mov y,ax                        { repeat ... }
  207.         mov cx,[di]
  208.         mov dx,[di+2]
  209.         mov px1,cx
  210.         mov px2,dx
  211.         push ax
  212.         push di
  213.         call @xhlin                     { xhlin(px1,px2,y,c) }
  214.         pop di
  215.         pop ax
  216.         add di,4                        { Next xpos }
  217.         inc ax                          { inc(y) }
  218.         cmp ax,mxy                      { ... until y>mxy; }
  219.         jle @Show
  220.         jmp @pexit
  221.  
  222. { RangeChk }
  223.  
  224. @Range: pop di                          { Get return IP }
  225.         pop py2                         { Get params }
  226.         pop px2
  227.         pop py1
  228.         pop px1
  229.         push di                         { Save return IP }
  230.  
  231.         mov ax,py1                      { dir:=byte(y1<y2) }
  232.         cmp ax,py2
  233.         mov ax,1
  234.         jl @Rdwn
  235.         dec al
  236. @Rdwn:  mov dir,al
  237.  
  238.         shl al,1
  239.         push ax
  240.         shl al,2
  241.         sub ax,4
  242.         mov stb,ax                      { stb:=8*dir-4 }
  243.         pop ax
  244.         dec ax                          { s:=2*dir-1 }
  245.         mov s,ax                        { Check directions (-1= down, 1=up) }
  246.  
  247.         test AH,10000000b               { Calculate constants }
  248.         mov dx,0
  249.         jz @Rposi
  250.         dec dx
  251. @Rposi: mov bx,px2
  252.         sub bx,px1
  253.         imul bx
  254.         mov mult,ax                     { mult:=s*(x2-x1) }
  255.         mov ax,py2
  256.         mov bx,py1
  257.         mov cx,ax
  258.         sub ax,bx
  259.         mov divi,ax                     { divi:=y2-y1 }
  260.  
  261.         cmp bx,cx                       { ¿y1=y2? }
  262.  
  263.         pushf                           { Calculate pointer to xpos[y,dir] }
  264.         mov y,bx                        { y:=y1 }
  265.         mov di,bx
  266.         shl di,2
  267.         lea bx,xpos
  268.         add di,bx
  269.         mov cl,dir
  270.         mov ch,0
  271.         shl cl,1
  272.         add di,cx                       { di points to xpos[y,dir] }
  273.         popf
  274.  
  275.         je @Requ                        { if y1=y2 ==> @Requ }
  276.  
  277.         mov m,0                         { m:=0 }
  278.         mov ax,py2
  279.         add ax,s
  280.         mov top,ax                      { top:=y2+s }
  281.  
  282. @RLoop: mov ax,y                        { repeat ... }
  283.         cmp ax,mny                      { if y<mny ==> @RNext }
  284.         jl @RNext
  285.         cmp ax,mxy                      { if y>mxy ==> @RNext }
  286.         jg @RNext
  287.  
  288.         mov ax,m                        { Calculate int(m/divi)+x1 }
  289.         test AH,10000000b
  290.         mov dx,0
  291.         jz @RLpos
  292.         dec dx
  293. @RLpos: mov bx,divi
  294.         idiv bx
  295.         add ax,px1
  296.         call @HR                        { HorRangeChk(m div divi+x1) }
  297.  
  298. @RNext: mov ax,mult
  299.         add m,ax                        { inc(m,mult) }
  300.         add di,stb                      { Next xpos }
  301.         mov ax,y                        { inc(y,s) }
  302.         add ax,s
  303.         mov y,ax
  304.         cmp ax,top
  305.         jne @RLoop                      { ... until y=top }
  306.         jmp @Rexit
  307.  
  308. @Requ:  mov ax,y
  309.         cmp ax,mny                      { if y<mny ==> Exit }
  310.         jl @Rexit
  311.         cmp ax,mxy                      { if y>mxy ==> Exit }
  312.         jg @Rexit
  313.         mov ax,px1
  314.         call @HR                        { HorRangeChk(px1) }
  315. @Rexit: jmp @exit
  316.  
  317. { HorRangeChk }
  318.  
  319. @HR:    mov bx,minx                     { bx:=minx }
  320.         cmp ax,bx
  321.         jl @HRsav
  322.         mov bx,maxx                     { bx:=maxx }
  323.         cmp ax,bx
  324.         jg @HRsav
  325.         mov bx,ax
  326. @HRsav: mov [di],bx                     { xpos[y,dir]:=bx }
  327.         jmp @exit
  328. { xhlin }
  329.  
  330. @xhlin: mov es,vidseg
  331.         cld
  332.         mov ax,80
  333.         mul y
  334.         mov di,ax                       { base of scan line }
  335.         add di,address
  336.  
  337.         mov bx,px1                      { px1 = x begin coord }
  338.         mov dx,px2                      { px2 = x end coord }
  339.         cmp bx,dx
  340.         jb @skip
  341.         xchg bx,dx                      { switch coords if px1>px2 }
  342.  
  343. @skip:  mov cl,bl
  344.         shr bx,2
  345.         mov ch,dl
  346.         shr dx,2
  347.         and cx,$0303
  348.         sub dx,bx                       { width in Bytes }
  349.         add di,bx                       { offset into video buffer }
  350.         mov ax,$ff02
  351.         shl ah,cl
  352.         and ah,1111b                    { left edge mask }
  353.         mov cl,ch
  354.         mov bh,$f1
  355.         rol bh,cl
  356.         and bh,1111b                    { right edge mask }
  357.         mov cx,dx
  358.         or cx,cx
  359.         jnz @left
  360.         and ah,bh                       { combine left & right bitmasks }
  361.  
  362. @left:  mov dx,$03c4
  363.         out dx,ax
  364.         inc dx
  365.         mov al,c
  366.         stosb
  367.         jcxz @exit
  368.         dec cx
  369.         jcxz @right
  370.         mov al,1111b
  371.         out dx,al                       { skipped if cx=0,1 }
  372.         mov al,c
  373.         repz stosb                      { fill middle Bytes }
  374.  
  375. @right: mov al,bh
  376.         out dx,al                       { skipped if cx=0 }
  377.         mov al,c
  378.         stosb
  379.  
  380. @exit:  pop ax
  381.         push cs
  382.         push ax
  383.         ret
  384. @pexit:
  385. end;
  386.  
  387. {$f+}
  388.  
  389. Function cosinus(i:byte):integer;
  390. begin
  391.  cosinus:=ctab[i];
  392. end;
  393.  
  394. Function sinus(i:byte):integer;
  395. begin
  396.  sinus:=stab[i];
  397. end;
  398.  
  399. Procedure Initialize;
  400. var i:byte;
  401. begin
  402.  triangles:=False;
  403.  for i:=0 to 255 do ctab[i]:=round(-cos(i*pi/128)*divd);
  404.  for i:=0 to 255 do stab[i]:=round(sin(i*pi/128)*divd);
  405. end;
  406.  
  407. begin
  408.  Initialize;
  409. end.
  410.